home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol1 / Audio / SimpleAudio < prev   
Encoding:
Text File  |  1999-10-27  |  6.3 KB  |  167 lines

  1. (c)  Copyright 1989-1999 Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice, and 
  3. is provided "as is" without warranty of any kind, either expressed or implied.  
  4. The entire risk as to the use of this information is assumed by the user.
  5.  
  6.  
  7.  
  8.  
  9.                             Simple Audio
  10.  
  11.                             by Dan Baker     
  12.  
  13.  
  14. The code shown below allows you to generate a tone with the Amiga's audio
  15. hardware.  Use the frequency variable to set the pitch in Hz.  Use the
  16. duration variable to set the duration of the tone in seconds.
  17.  
  18. Audio device IO is handled mainly through the IOAudio structure which is
  19. defined in the audio.h header file.  To make a tone, you open the audio
  20. device and send commands to it using the IOAudio structure.  When you are
  21. finished, close the device.
  22.  
  23. In the example below, most of the code is used to initialize fields in the 
  24. IOAudio structure.  For instance, the structure is filled in with channel
  25. allocation information just before the  audio device is opened.  This will
  26. cause a channel to be allocated automatically when the device is opened.
  27.  
  28. The Amiga has a complex allocation and arbitration scheme which is
  29. described in detail in the ROM Kernel Manuals from Addison-Wesley.  For
  30. now though just remember that the array whichannel[] tells the Amiga that 
  31. you want any one of the four audio channels.
  32.  
  33. After the audio device has been opened the IOAudio structure is initialized 
  34. to play a note.  In the example, AllocMem() is used to reserve two bytes of 
  35. chip memory for the wave data which in this case is a very simple square wave.  
  36. The address of the two byte sample is used in the IOAudio structure along with
  37. computed values for playback sampling rate, sample length and number of cycles.
  38.  
  39. The command is sent to the audio device using BeginIO().  Once the command is
  40. sent, Wait() is called which puts the task to sleep untill the audio device 
  41. has finished the command.  Finally, GetMsg() is used to clear the reply from 
  42. the audio device which is then closed with CloseDevice().
  43.  
  44. In the example below, a 2 byte sample is used.  To avoid aliasing distortion
  45. the length of the sample should be increased to 32 bytes and the period
  46. should be restricted to the range 124-256.  This will limit the tones that
  47. can be produced to a one-octave range.  You can find more information on
  48. aliasing distortion and other audio topics in the Amiga Hardware Manual and
  49. in the Amiga ROM Kernel Manuals, both published by Addison-Wesley.
  50.  
  51.  
  52.  
  53.  
  54.  
  55. #include "exec/types.h"
  56. #include "exec/memory.h"
  57. #include "devices/audio.h"
  58. #include "graphics/gfxbase.h"
  59.  
  60. struct GfxBase *GfxBase;
  61. struct Message *GetMsg();
  62. struct MsgPort *CreatePort();
  63. APTR            OpenLibrary();
  64. APTR            AllocMem();
  65. ULONG           OpenDevice();
  66. UBYTE           whichannel[] = { 1,2,4,8 };
  67.  
  68. void
  69. main()
  70. {
  71. struct IOAudio *AudioIOBptr;
  72. struct MsgPort *port;
  73. struct Message *msg;
  74. BYTE           *waveptr;
  75. ULONG           device;
  76. LONG            frequency=440;        /* frequency of the tone           */
  77. LONG            duration =3;          /* duration in seconds             */
  78. LONG            clock    =3579545;    /* Clock constant, 3546895 for PAL */
  79. LONG            samples  =2;          /* Number of sample bytes          */
  80.  
  81.  
  82. /*---------------------------------------*/
  83. /* Ask the system if we are PAL or NTSC  */
  84. /* and set clock constant accordingly    */
  85. /*---------------------------------------*/
  86. GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L);
  87. if(GfxBase==0L) goto killaudio;
  88. if(GfxBase->DisplayFlags & PAL) clock=3546895;        /* PAL clock */
  89. else                            clock=3579545;        /* NTSC clock */
  90. if(GfxBase)CloseLibrary(GfxBase);
  91.  
  92.  
  93. /*------------------------------*/
  94. /* Allocate audio I/O blocks    */
  95. /*------------------------------*/
  96. AudioIOBptr=(struct IOAudio *)
  97.          AllocMem( sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR);
  98. if(AudioIOBptr==0) goto killaudio;
  99. printf("IO block allocated...\n");
  100.  
  101.  
  102. /*-----------------------------------------------*/
  103. /* Set up audio I/O block for channel allocation */
  104. /*-----------------------------------------------*/
  105. port=CreatePort(0,0);
  106. if(port==0) goto killaudio;
  107. printf("Port created...\n");
  108.  
  109. AudioIOBptr->ioa_Request.io_Message.mn_ReplyPort   = port;
  110. AudioIOBptr->ioa_Request.io_Message.mn_Node.ln_Pri = 0;
  111. AudioIOBptr->ioa_Request.io_Command                = ADCMD_ALLOCATE;
  112. AudioIOBptr->ioa_Request.io_Flags                  = ADIOF_NOWAIT;
  113. AudioIOBptr->ioa_AllocKey                          = 0;
  114. AudioIOBptr->ioa_Data                              = whichannel;
  115. AudioIOBptr->ioa_Length                            = sizeof(whichannel);
  116. printf("IO block initialized for channel allocation...\n");
  117.  
  118.  
  119. /*-----------------------------------------------*/
  120. /* Open the audio device and allocate a channel  */
  121. /*-----------------------------------------------*/
  122. device=OpenDevice("audio.device",0,AudioIOBptr,0);
  123. if(device!=0) goto killaudio;
  124. printf("Audio device opened, channel allocated...\n");
  125.  
  126.  
  127. /*-----------------------------------------*/
  128. /* Set up audio I/O block to make a sound. */
  129. /*-----------------------------------------*/
  130. waveptr=(BYTE *)AllocMem( samples , MEMF_CHIP|MEMF_PUBLIC);
  131. if(waveptr==0) goto killaudio;
  132. waveptr[0]=  127;
  133. waveptr[1]= -127;
  134. printf("Wave data ready...\n");
  135.  
  136. AudioIOBptr->ioa_Request.io_Message.mn_ReplyPort = port;
  137. AudioIOBptr->ioa_Request.io_Command              = CMD_WRITE;
  138. AudioIOBptr->ioa_Request.io_Flags                = ADIOF_PERVOL;
  139. AudioIOBptr->ioa_Data                            = (BYTE *)waveptr;
  140. AudioIOBptr->ioa_Length                          = samples;
  141. AudioIOBptr->ioa_Period                          = clock/(samples*frequency);
  142. AudioIOBptr->ioa_Volume                          = 64;
  143. AudioIOBptr->ioa_Cycles                          = frequency*duration;
  144. printf("IO block initialized to play tone...\n");
  145.  
  146. /*-----------------------------------*/
  147. /* Send the command to start a sound */
  148. /*-----------------------------------*/
  149. printf("Sarting tone now...\n");
  150. BeginIO(AudioIOBptr);
  151. Wait(1 << port->mp_SigBit);
  152. msg=GetMsg(port);
  153.  
  154. printf("Sound finished...\n");
  155.  
  156. killaudio:
  157.  
  158.   printf("Killing audio device...\n");
  159.   if(waveptr!=0)     FreeMem(waveptr, 2);
  160.   if(port!=0)        DeletePort(port);
  161.   if(device==0)      CloseDevice(AudioIOBptr);
  162.   if(AudioIOBptr!=0) FreeMem( AudioIOBptr,sizeof(struct IOAudio) );
  163. }
  164.  
  165.  
  166.  
  167.